#!/bin/bash
# set -x
start_time_s=$(date +%s)
WORK_PATH=$(readlink -f ${0} | xargs dirname)
script_name=$(basename $0)
script_param=$@

cfg_file=${WORK_PATH}/.${script_name%\.*}.conf
source ${cfg_file}
lock_file="${WORK_PATH}/.${script_name%\.*}.lock"

# log
log_path="${WORK_PATH}/log/$(date +%Y%m%d)"
log="${log_path}/$(date +%Y%m%d%H%M%S)_${script_name%\.*}_${script_param// /_}.log"

# environment
env_path="${WORK_PATH}/env"
build_docker_cfg="${env_path}/build_docker_image_cfg.conf"
build_sdk_cfg="${env_path}/build_sdk_cfg.conf"
test_docker_cfg="${env_path}/test_docker_cfg.conf"
build_sdk_is_upgraded=false

# backup
backup_expiration_time=$(date -d "20 day ago" +%Y%m%d)
docker_back_path="${WORK_PATH}/docker_back"
backup_path="${WORK_PATH}/backup/$(date +%Y%m%d)"
backup_build_sdk_path="${backup_path}"
backup_test_docker_image_path="${backup_path}/test_docker_image"
backup_log_path="${backup_path}/log"
yesterday=$(date -d "1 day ago" +%Y%m%d)

# source code
src_path="${WORK_PATH}/git_src"
build_install_path="${WORK_PATH}/build_install"


######################################################
# common function
######################################################
function usage
{
    echo "Usage: $(basename $0) command [test-unit]"
    echo "command:"
    echo "    help            Show list of command-line options"
    echo "    init-env        Initialize or upgrade the build and test environment."
    echo "    show-env        Display build and test environment info."
    echo "    reset-env       Reset test environment."
    echo "    restart-env     Restart test environment."

    echo "    update          Update source code from git."
    echo "    delete          Delete source code from local that is not managed by git."
    echo "    delete-log      Delete log from 14 day ago."

    echo "    build           Build and install the source code into the test environment."
    echo "    test            Execute test in the test environment."
    echo "    build-test      Build and install the source code into the test environment and then execute the test script in Docker."
    echo ""

    echo "test-unit:"
    echo "    all             all unit."
    for unit_name in ${!TEST_TARGET[@]}; do
        if [[ ${unit_name} != "" ]]; then
            echo "    ${unit_name}            ${unit_name} unit."
        fi
    done
}

function start_execute
{
    if [[ -e ${lock_file} ]]; then
        echo -e "\e[31m[ERR ] Others are using the current environment.\e[m"
        exit 1
    else
        # create lock file
        touch ${lock_file}
        # init log file
        if [[ -e ${log_path} ]]; then
            :> ${log}
        else
            mkdir -p ${log_path}
            :> ${log}
        fi

        find ${WORK_PATH}/log -type d -mtime +30 -exec rm -rf {} \;

        echo "#####################################################"            | tee -a ${log}
        echo "# [INFO] Execute Command : ${script_name} ${script_param}"        | tee -a ${log}
        echo "# [INFO] Start Time      : $(date +%Y/%m/%d-%H:%M:%S)"            | tee -a ${log}
        echo "#####################################################"            | tee -a ${log}
    fi
}
function normal_exit
{
    # delete lock file.
    if [[ -e ${lock_file} ]]; then
        rm -fr ${lock_file}
    fi
    local end_time_s=$(date +%s)
    echo "#####################################################"                | tee -a ${log}
    echo "# [INFO] Eexecute command normal end."                                | tee -a ${log}
    echo "# [INFO] End Time       : $(date +%Y/%m/%d-%H:%M:%S)"                 | tee -a ${log}
    echo "# [INFO] Execution Time : $[ $end_time_s - $start_time_s ]s"          | tee -a ${log}
    echo "# [INFO] The Log log storage path => ${log_path}"                      | tee -a ${log}
    echo "#####################################################"                | tee -a ${log}
    exit 0
}
function abnormal_exit
{
    # delete lock file.
    if [[ -e ${lock_file} ]]; then
        rm -fr ${lock_file}
    fi
    local end_time_s=$(date +%s)
    echo "#####################################################"                | tee -a ${log}
    echo "# [ERR ] Eexecute command abnormal end."                              | tee -a ${log}
    echo "# [ERR ] End Time       : $(date +%Y/%m/%d-%H:%M:%S)"                 | tee -a ${log}
    echo "# [ERR ] Execution Time : $[ $end_time_s - $start_time_s ]s"          | tee -a ${log}
    echo "# [ERR ] The Log log storage path => ${log_path}"                      | tee -a ${log}
    echo "#####################################################"                | tee -a ${log}
    exit 1
}

######################################################
# Git clone and update function
#
# @function   git_clone_update
# @param      1:git_repo_url
# @param      2:git_repo_name
# @param      3:git_repo_branch
# @param      4:git_repo_branch_commitid
#
# @ return 
#             0:Success
#             1:Failure
######################################################
function git_clone_update
{
    local git_repo_url=$1
    local git_repo_name=$2
    local git_repo_branch=$3
    local git_repo_branch_commitid=$4
    echo "------------------------------------------------------"               >> ${log}
    echo "[INFO] Start update ${git_repo_name} from ${git_repo_url}"            >> ${log}
    # echo "------------------------------------------------------"               >> ${log}

    if [[ ${git_repo_url} != "" ]] && [[ ${git_repo_name} != "" ]] && [[ ${git_repo_branch} != "" ]]; then
        # git pull
        if [[ -e ${git_repo_name}/.git ]] ;then
            cd ${git_repo_name}
            # reset branch
            git reset --hard HEAD    >> ${log} 2>&1
            git clean -df            >> ${log} 2>&1
            if [[ $? -ne 0 ]]; then
                echo "[ERR ] Failed to git clean branch." >> ${log}
                return 1
            fi

            # switch default branch
            local default_branch=$(git branch -r --points-at refs/remotes/origin/HEAD | grep '\->' | cut -d' ' -f5 | cut -d/ -f2)
            if [[ $(git rev-parse --abbrev-ref HEAD) != "${default_branch}" ]]; then
                git switch ${default_branch}    >> ${log} 2>&1
                if [[ $? -ne 0 ]]; then
                    echo "[ERR ] Failed to switch default branch =>${default_branch}" >> ${log}
                    return 1
                fi
            fi

            # delete other local branch
            git branch -D $(git branch -l |grep -v ${default_branch})    >> ${log} 2>&1
            # sync remote branch name
            git remote prune origin                                      >> ${log} 2>&1
            
            # update all branch
            git pull     >> ${log} 2>&1
            if [[ $? -ne 0 ]]; then
                echo "[ERR ] Failed to git pull branch." >> ${log}
                return 1
            fi
        # git clone
        else
            # clone repository
            rm -fr ${git_repo_name}
            echo "Cloning into ${git_repo_name} ..."    >> ${log}
            git clone --progress ${git_repo_url} ${git_repo_name} 2> ${log_path}/.git_progress.log 1>> ${log}
            if [[ $? -ne 0 ]]; then
                echo "[ERR ] Failed to git clone repo. repo_url=>${repo_url}"   >> ${log}
                return 1
            fi
            cd ${git_repo_name}
        fi

        # switch branche
        if [[ $(git rev-parse --abbrev-ref HEAD) != "${git_repo_branch}" ]]; then
            git switch ${git_repo_branch}    >> ${log} 2>&1
            if [[ $? -ne 0 ]]; then
                echo "[ERR ] Failed to git switch branch. branch=>${git_repo_branch}" >> ${log}
                return 1
            fi
        fi

        # reset commit id
        if [[ ${git_repo_branch_commitid} != "" ]];then
            echo "[INFO] Exec command=>$ git reset --hard ${git_repo_branch_commitid}"
            git reset --hard ${git_repo_branch_commitid}
            if [[ $? -ne 0 ]]; then
                echo "[ERR ] Failed to git reset --hard ${git_repo_branch_commitid}" >> ${log}
                return 1
            fi
        fi
        cd - >/dev/null
    else
        echo "[ERR ] Failed to update ${git_repo_name}:${git_repo_branch} from ${git_repo_url}"   >> ${log}
        return 1
    fi
    # echo "------------------------------------------------------"               >> ${log}
    echo "[INFO] Successfully update ${git_repo_name} from ${git_repo_url}"     >> ${log}
    echo "------------------------------------------------------"               >> ${log}
    # echo ""                                                                     >> ${log}
    return 0
}

######################################################
# Get the current branch of the specified repo path.
# @param 
#        1: repositories path
#
# @ return 
#             0:Success
#             1:Failure
######################################################
function get_git_branch
{
    pushd $1 >/dev/null
    {
        branch=$(git rev-parse --abbrev-ref HEAD)
        if [[ $? -ne 0 ]]; then 
            echo "[ERR ] line:${LINENO} Failed to get the current branch of the specified repo path. "  >> ${log}
            return 1
        else
            echo "${branch}"
            return 0
        fi
    }
    popd >/dev/null
}
######################################################
# Get the current version of the specified repo path.
# @param 
#        1: repositories path
#
# @ return 
#             0:Success
#             1:Failure
######################################################
function get_git_version
{
    pushd $1 >/dev/null
    {
        version=$(git rev-parse HEAD)
        if [[ $? -ne 0 ]]; then 
            echo "[ERR ] line:${LINENO} Failed to get the current version of the specified repo path. "  >> ${log}
            return 1
        else
            echo "${version}"
            return 0
        fi
    }
    popd >/dev/null
}

######################################################
# Manage backup files
# @param 
#        none
#
# @ return 
#             0:Success
#             1:Failure
######################################################
function backup_manager
{
    echo "======================================================"     >> ${log}
    echo "[INFO] Start manage backup files."                          >> ${log}

    
    if [[ ! -e ${docker_back_path} ]]; then
        mkdir -p ${docker_back_path}
    else
        find ${docker_back_path} -type f -mtime +30 -exec rm -rf {} \;
    fi

    pushd $(dirname ${backup_path}) >> ${log}
    {
        for dir_name in $(ls .) ; do 
            if [[ -d ${dir_name} && ${dir_name} -lt ${backup_expiration_time} ]]; then
                echo "[INFO] delete outdated backup files=>${dir_name} "  >> ${log}
                rm -fr ${dir_name}  >> ${log} 2>&1
                if [[ $? -ne 0 ]]; then
                    echo "[ERR ] line:${LINENO} Failed to delete outdated backup files. "  | tee -a ${log}
                    echo "======================================================"      >> ${log}
                    return 1
                fi
            fi
        done

        # Backup yesterday's logs
        if [[ ! -e $(date +%Y%m%d)/${yesterday}_log ]]; then
            mkdir -p $(date +%Y%m%d)/${yesterday}_log
        fi
        cp -r ${WORK_PATH}/log/${yesterday}* $(date +%Y%m%d)/${yesterday}_log/
        if [[ $?  -ne 0 ]]; then
            echo "[ERR ] line:${LINENO} Failed to Backup yesterday's logs." | tee -a ${log}
        else
            echo "[INFO ] line:${LINENO} Backup yesterday's logs Success." | tee -a ${log}
        fi
        echo "======================================================"      >> ${log}
    }
    popd >> ${log}

    echo "[INFO] Successfully manage backup files."                    >> ${log}
    echo "======================================================"      >> ${log}
    echo ""                                                            >> ${log}
    return 0
}
######################################################
# Upgrade build environment.
# @param 
#             $1 : sdk version number
# @ return 
#             0:Success
#             1:Failure
######################################################
function upgrade_build_env
{
    echo "======================================================"      >> ${log}
    echo "[INFO] Start upgrade build docker image."                    >> ${log}

    # Check build docker image.
    echo "[INFO] Check build docker image."                                 >> ${log}
    local docker_image_name="${BUILD_DOCKER_REPOSITORY}"
    local docker_image_tag="${BUILD_DOCKER_TAG}"
    local curr_docker_image_id=$(docker images ${docker_image_name}:${docker_image_tag} --format "{{.ID}}")
    ## The build docker image needs to be upgrade.
    if [[ ${curr_docker_image_id} == "" ]]; then
        echo "[INFO] The build docker image does not exists."              >> ${log}
        
        ### Download and update source code of the build docker image.
        echo "[INFO] Download and update source code of the build docker image. "  >> ${log}
        local docker_git_cfg=(${GIT_ENV_REPO[build_docker]//:/ })
        local git_repo=${docker_git_cfg[1]}
        local git_branch=${docker_git_cfg[2]}
        local script_command=${docker_git_cfg[3]}
        local git_repo_url=${GIT_ENV_URL}/${docker_git_cfg[0]}/${git_repo}
        pushd ${env_path}  >> ${log}
        {
            git_clone_update ${git_repo_url} ${git_repo} ${git_branch}
            if [[ $? -ne 0 ]]; then
                echo "[ERR ] line:${LINENO} Failed to download and update source code of the build docker image. "  | tee -a ${log}
                echo "======================================================"      >> ${log}
                return 1
            fi
            local curr_version=$(get_git_version ${git_repo})
        }
        popd >> ${log}
        echo "[INFO] Branch=${git_branch}; Current Version=${curr_version}" >> ${log}
        echo "[INFO] Successfully download and update source code of the build docker image. "  >> ${log}

        ### Install build docker image from source code.
        echo "[INFO] The build docker image installing ..."  >> ${log}
        pushd ${env_path}/${git_repo} >> ${log}
        {
            sed -ri '1,3s/ubuntu-18.04/ubuntu-20.04/g' ./Dockerfile
            sed -ri 's/(^\s+python-git \\$)/#\1/g' ./Dockerfile
            #### install build docker
            docker build --build-arg http_proxy=${http_proxy} --build-arg https_proxy=${https_proxy} -t ${docker_image_name}:${docker_image_tag} .
            if [[ $?  -ne 0 ]]; then
                echo "[ERR ] line:${LINENO} Failed to install build docker image=>${docker_image_name}:${docker_image_tag} ." | tee -a ${log}
                echo "======================================================"      >> ${log}
                return 1
            fi
            curr_docker_image_id=$(docker images ${docker_image_name}:${docker_image_tag} --format "{{.ID}}")

            #### check install status
            if [[ ${curr_docker_image_id} == "" ]]; then
                echo "[ERR ] line:${LINENO} The installed build docker image[${docker_image_name}:${docker_image_tag}] does not exist." | tee -a ${log}
                echo "======================================================"      >> ${log}
                return 1
            fi
        }
        popd >> ${log}
        echo "[INFO] Installed build docker image=${docker_image_name}:${docker_image_tag}."  >> ${log}
        echo "[INFO] Successfully install build docker image from source code. "  >> ${log}    
    ## The build docker image does not needs to be upgrade.
    else
        echo "[INFO] The build docker image already exists. ID=>${curr_docker_image_id}" >> ${log}
    fi

    # Save build docker info 
    echo "[INFO] Save build docker image info to file=>${build_docker_cfg}" >> ${log}
    if [[ -e ${build_docker_cfg} ]]; then
        sed -ri "4,6s#(REPOSITORY:).*#\1 ${docker_image_name}#g"  ${build_docker_cfg}
        sed -ri "4,6s#(TAG:).*#\1 ${docker_image_tag}#g"          ${build_docker_cfg}
        sed -ri "4,6s#(ID:).*#\1 ${curr_docker_image_id}#g"       ${build_docker_cfg}

        sed -ri "10,12s#(Repositories:).*#\1 ${git_repo}#g"       ${build_docker_cfg}
        sed -ri "10,12s#(Branch:).*#\1 ${git_branch}#g"           ${build_docker_cfg}
        sed -ri "10,12s#(CommitID:).*#\1 ${curr_version}#g"       ${build_docker_cfg}
    else
        echo "######################################################"  >  ${build_docker_cfg}
        echo "# The current build docker image info."                 >> ${build_docker_cfg}
        echo "######################################################"  >> ${build_docker_cfg}
        echo "REPOSITORY: ${docker_image_name}" >> ${build_docker_cfg}
        echo "TAG: ${docker_image_tag}"         >> ${build_docker_cfg}
        echo "ID: ${curr_docker_image_id}"      >> ${build_docker_cfg}
        echo "######################################################"  >> ${build_docker_cfg}
        echo "# The source code of the currently built docker image."  >> ${build_docker_cfg}
        echo "######################################################"  >> ${build_docker_cfg}
        echo "Repositories: ${git_repo}"        >> ${build_docker_cfg}
        echo "Branch: ${git_branch}"            >> ${build_docker_cfg}
        echo "CommitID: ${curr_version}"        >> ${build_docker_cfg}
    fi

    echo "[INFO] Successfully upgrade build docker image."             >> ${log}
    echo "======================================================"      >> ${log}
    echo ""                                                            >> ${log}


    #############################################################################
    # Upgrade build sdk
    #############################################################################
    echo "======================================================"      >> ${log}
    echo "[INFO] Start upgrade build sdk."                             >> ${log}

    # Check build sdk version.
    echo "[INFO] Check build sdk version."                             >> ${log}
    local isUpgrade=false
    local wget_sdk_url=""
    local sdk_data_version=""
    local sdk_install_file=""
    local curr_date=$(date +%Y%m%d)
    if [[ -z ${SDK_DATE_VERSION_CURRENT} || ${curr_date} -gt ${SDK_DATE_VERSION_CURRENT%%_*} ]]; then
        for ((index=0; index<${#SDK_DATE_VERSION_LIST[@]}; index++)); do
            local sdk_date=$(echo ${SDK_DATE_VERSION_LIST[index]} | awk -F '_' '{print $1}')
            local sdk_version=$(echo ${SDK_DATE_VERSION_LIST[index]} | awk -F '_' '{print $3}' |sed 's/.[A-Z]//g')
            local next_index=$((index+1))
            if [[ ${next_index} -ge ${#SDK_DATE_VERSION_LIST[@]} ]]; then
                echo "[ERR ] line:${LINENO} Please update the SDK_DATE_VERSION_LIST,There is no more upgradeable version." | tee -a ${log}
                echo "======================================================"      >> ${log}
                return 1
            fi 
            local sdk_date_next=$(echo ${SDK_DATE_VERSION_LIST[next_index]} | awk -F '_' '{print $1}')
            local sdk_version_next=$(echo ${SDK_DATE_VERSION_LIST[next_index]} | awk -F '_' '{print $3}' |sed 's/.[A-Z]//g')

            if [[ ${curr_date} -gt $(date -d "1 day ago ${sdk_date}" ++%Y%m%d) ]]; then 
                if [[ ${curr_date} -lt $(date -d "1 day ago ${sdk_date_next}" ++%Y%m%d) ]]; then 
                    sdk_data_version=${SDK_DATE_VERSION_LIST[index]}
                    wget_sdk_url=$(echo ${WGET_SDK_URL} | sed "s/{--SDK_DATE_VERSION--}/${sdk_data_version}/g" | sed "s/{--SDK_VERSION--}/${sdk_version%-*}/g")
                    isUpgrade=true
                    break
                else
                    continue
                fi 
            else
                break
            fi
        done
    fi
    
    ## The build sdk needs to be upgrade and backup.
    if [[ ${isUpgrade} == "true" && ${sdk_data_version} != ${SDK_DATE_VERSION_CURRENT} ]]; then
        echo "[INFO] The build sdk needs to be upgrade and backup."                        >> ${log}
        pushd ${env_path}  >> ${log} 
        {
            ### Check new build sdk url.
            echo "[INFO] Check new build sdk url."                              >> ${log}
            wget --spider -T 5 -q -t 3 ${wget_sdk_url}
            if [[ $? -ne 0 ]]; then
                echo "[ERR ] line:${LINENO} The new build SDK url does not exists. sdk url=${wget_sdk_url}." | tee -a ${log}
                echo "======================================================"      >> ${log}
                return 1
            fi 
             
            ### Delet old build sdk.
            echo "[INFO] Delet old build sdk."                                  >> ${log}
            rm -fr sdk  >> ${log} 2>&1  && rm -fr arene-toolchain-cockpit-ivi-*-genericx86-64.sh  >> ${log} 2>&1
            if [[ $? -ne 0 ]]; then
                echo "[ERR ] line:${LINENO} Failed to delete old build sdk file. "  | tee -a ${log}
                echo "======================================================"      >> ${log}
                return 1
            fi 

            ### Download new build sdk.
            echo "[INFO] Download new build sdk."                               >> ${log}
            sdk_install_file=${wget_sdk_url##*/}
            wget -T 5 -t 3 -O ${sdk_install_file} ${wget_sdk_url} 2>./.wget_sdk_progress.log
            if [[ $?  -ne 0 ]]; then
                echo "[ERR ] line:${LINENO} Failed to download new build sdk. sdk url=${wget_sdk_url}." | tee -a ${log}
                echo "======================================================"      >> ${log}
                return 1
            fi


            ### Install new build sdk.
            echo "[INFO] Install new build sdk."                                >> ${log}
            # docker run --rm -it -v ~:/home/hosthome:ro -v ${WORK_PATH}:/workdir --name poky-$(id -un)-arene_source \
            docker run --rm -v ~:/home/hosthome:ro -v ${WORK_PATH}:/workdir --name poky-$(id -un)-arene_source \
                --workdir=/workdir ${BUILD_DOCKER_REPOSITORY}:${BUILD_DOCKER_TAG} \
                    bash -c " pwd; \
                        ls ./env; \
                        bash ./env/${sdk_install_file} -y -d ./env/sdk; \
                        exit" >> ${log} 2>&1
            if [[ $?  -ne 0 ]]; then
                echo "[ERR ] line:${LINENO} Failed to install new build sdk. sdk install file=>${sdk_install_file}" | tee -a ${log}
                echo "======================================================"      >> ${log}
                return 1
            else
                build_sdk_is_upgraded=true
            fi

            ### Backup the new build sdk installation file. 
            echo "[INFO] Backup the new build sdk installation file to backup_path=>${backup_build_sdk_path}/${sdk_data_version}"  >> ${log}
            if [[ ! -e ${backup_build_sdk_path}/${sdk_data_version} ]]; then
                mkdir -p ${backup_build_sdk_path}/${sdk_data_version}
            else
                rm -rf ${backup_build_sdk_path}/${sdk_data_version}/*
                :>${backup_build_sdk_path}/${sdk_data_version}/sdk.conf
            fi
            cp -fr ${sdk_install_file} ${backup_build_sdk_path}/${sdk_data_version}
            if [[ $?  -ne 0 ]]; then
                echo "[ERR ] line:${LINENO} Failed to backup the new build sdk installation file. sdk install file=>${sdk_install_file}" | tee -a ${log}
                echo "======================================================"      >> ${log}
                return 1
            fi

            echo "SDK_VERSION=${sdk_version}"                      >> ${backup_build_sdk_path}/${sdk_data_version}/sdk.conf
            echo "SDK_DATE_VERSION=${sdk_data_version}"            >> ${backup_build_sdk_path}/${sdk_data_version}/sdk.conf
        }
        popd >> ${log}

        ### Update config file 
        echo "[INFO] Update the version of the build sdk in the configuration file."  >> ${log}
        sed -ri "s/(^SDK_DATE_VERSION_CURRENT)=.*$/\1=${sdk_data_version}/g"  ${cfg_file}
        if [[ $?  -ne 0 ]]; then
            echo "[ERR ] line:${LINENO} Failed to update build sdk version=>${sdk_data_version}" | tee -a ${log}
            echo "======================================================"      >> ${log}
            return 1
        fi
    ## The build sdk does not need to be upgrade and backup.
    else
        echo "[INFO] The build sdk does not need to be upgrade and backup."  >> ${log}
        sdk_data_version=${SDK_DATE_VERSION_CURRENT}
        local sdk_version=$(echo ${sdk_data_version} | awk -F '_' '{print $3}' |sed 's/.[A-Z]//g')
        wget_sdk_url=$(echo ${WGET_SDK_URL} | sed "s/{--SDK_DATE_VERSION--}/${sdk_data_version}/g" | sed "s/{--SDK_VERSION--}/${sdk_version}/g")
        sdk_install_file=$(echo ${WGET_SDK_URL##*/} | sed "s/{--SDK_VERSION--}/${sdk_version}/g")
    fi

    # Save build sdk info
    echo "[INFO] Save build sdk info to file=>${build_sdk_cfg}"  >> ${log}
    echo "$wget_sdk_url"
    if [[ -e ${build_sdk_cfg} ]]; then
        sed -ri "4,6s#(BUILD_SDK_URL:).*#\1 ${wget_sdk_url}#g"            ${build_sdk_cfg}
        sed -ri "4,6s#(BUILD_SDK_VERSION:).*#\1 ${sdk_data_version}#g"    ${build_sdk_cfg}
        sed -ri "4,6s#(BUILD_SDK_FILE:).*#\1 ${sdk_install_file}#g"       ${build_sdk_cfg}
    else
        echo "######################################################"  >  ${build_sdk_cfg}
        echo "# The current build sdk info."                          >> ${build_sdk_cfg}
        echo "######################################################"  >> ${build_sdk_cfg}
        echo "BUILD_SDK_URL: ${wget_sdk_url}"                 >> ${build_sdk_cfg}
        echo "BUILD_SDK_VERSION: ${sdk_data_version}"         >> ${build_sdk_cfg}
        echo "BUILD_SDK_FILE: ${sdk_install_file}"            >> ${build_sdk_cfg}
    fi

    echo "[INFO] Successfully upgrade build sdk."                      >> ${log}
    echo "======================================================"      >> ${log}
    echo ""                                                            >> ${log}
    return 0
}

######################################################
# Upgrade runtime environment.
# @param 
#             $1 : runtime version number
# @ return 
#             0:Success
#             1:Failure
######################################################
function upgrade_runtime_env
{
    echo "======================================================"      >> ${log}
    echo "[INFO] Start upgrade test docker image."                     >> ${log}

    local isUpgrade=false
    local curr_date=$(date +%Y%m%d)
    for docker_ver_date in ${DOCKER_VERSION_LIST[@]}; do
        local tmp_date=(${docker_ver_date//:/ })
        local start_date=${tmp_date[0]}
        local end_date=${tmp_date[1]}
        local docker_version=${tmp_date[2]}
        if [[ ${curr_date} -ge ${start_date} ]] && [[ ${curr_date} -le ${end_date} ]]; then
            isUpgrade=true
            break
        fi
    done

    if [[ ${isUpgrade} == "true" ]]; then
        echo "[INFO] The test docker need to be upgrade and backup."  >> ${log}
    else
        echo "[INFO] The test docker does not need to be upgrade and backup."  >> ${log}
        return 0
    fi
    
    local docker_git_cfg=(${GIT_ENV_REPO[test_docker]//:/ })
    local git_repo=${docker_git_cfg[1]}
    local git_branch=${docker_git_cfg[2]}
    local script_command=${docker_git_cfg[3]}
    local git_repo_url=${GIT_ENV_URL}/${docker_git_cfg[0]}/${git_repo}

    # Download and update test docker config source code.
    echo "[INFO] Download and update test docker config source code."  >> ${log}
    pushd ${env_path}  >> ${log}
    {
        git_clone_update ${git_repo_url} ${git_repo} ${git_branch}
        if [[ $? -ne 0 ]]; then
            echo "[ERR ] line:${LINENO} Failed to download and update test docker config source code. "  | tee -a ${log}
            echo "======================================================"      >> ${log}
            return 1
        fi
        local curr_version=$(get_git_version ${git_repo})
    }
    popd  >> ${log}


    # Upgrade and backup test docker image.
    echo "[INFO] Upgrade and backup test docker image."  >> ${log}
    pushd ${env_path}/${git_repo}  >> ${log}
    {
        ## Modify test docker config info
        echo "[INFO] Modify test docker config info."  >> ${log}
        sed -ri 's/(^\s+setup$)/#\1/g' ./arene-ivi_docker.sh
        sed -ri 's/(^\s+xhost \+$)/#\1/g' ./arene-common_docker.sh
        sed -i '/function start_app() {$/a\    sleep 5' ./arene-common_docker.sh
        sed -i '/function start_app() {$/a\    export ARENE_IVI_HAL_MODE=MOCK' ./arene-common_docker.sh
        sed -i "/function start_app() {$/a\    export DISPLAY=:1.0" ./arene-common_docker.sh
        sed -i '/function start_app() {$/a\    fi' ./arene-common_docker.sh
        sed -i "/function start_app() {$/a\        sleep 30" ./arene-common_docker.sh
        sed -i '/function start_app() {$/a\        Xvfb :1 -screen 0 1280x720x24 &' ./arene-common_docker.sh
        sed -i '/function start_app() {$/a\    else' ./arene-common_docker.sh
        sed -i '/function start_app() {$/a\        echo "[info] Xvfb is exist info = [${Xvfb_info}]"' ./arene-common_docker.sh
        sed -i '/function start_app() {$/a\    if [[ ${Xvfb_info} ]]; then' ./arene-common_docker.sh
        sed -i '/function start_app() {$/a\    local Xvfb_info=$(ps -ef | grep [X]vfb)' ./arene-common_docker.sh
        sed -i '/function start_app() {$/a\    # set virtual display' ./arene-common_docker.sh
        sed -ri "s@(^\s+sudo rm -rf /tmp/arene$)@#\1@g" ./arene-common_docker.sh
        sed -i 's@sudo chown ${uid}:${uid} ${xdg_runtime_dir}/pulse -R@#sudo chown ${uid}:${uid} ${xdg_runtime_dir}/pulse -R@g' ./arene-common_docker.sh
        sed -i 's/sudo chown ${uid}:${uid} ${xdg_runtime_dir}/#sudo chown ${uid}:${uid} ${xdg_runtime_dir}/g' ./arene-common_docker.sh
        sed -i 's@sudo chown ${uid}:${uid} /tmp/arene/pulse@#sudo chown ${uid}:${uid} /tmp/arene/pulse@g' ./arene-common_docker.sh
        sed -i 's@sudo chown 1500:1500 /tmp/arene/pulse@#sudo chown 1500:1500 /tmp/arene/pulse@g' ./arene-common_docker.sh
        sed -ri 's/(^DOCKER_IMAGE_HAL_NAME=sdk-docker-hal$)/\1-mock/g' ./sdk-hal-docker/.env
        sed -ri "s@WORK_DIR=~/hmifw_share@WORK_DIR=${WORK_PATH}@g" ./sdk-hal-docker/.env
        sed -ri "s@DOCKER_PULL_SKIP=0@DOCKER_PULL_SKIP=1@g" ./sdk-hal-docker/.env
        sed -ri 's/(^DOCKER_IMAGE_RUNTIME_NAME=sdk-docker-runtime$)/\1-dbg/g' ./sdk-hal-docker/.env
        # sed -ri 's/(^\s+docker-compose pull+$)/#\1/g' ./arene-common_docker.sh
        # # sed -ri 's@(^\s+elif grep -q "artifactory-ha.tmc-stargate.com" ~/.netrc > /dev/null 2>&1; then$)@#\1@g' ./arene-common_docker.sh
        # sed -ri 's@(^\s+docker-compose pull$)@#\1@g' ./arene-common_docker.sh
        # sed -ri 's@(^\s+fetch_docker_tarball$)@#\1@g' ./arene-common_docker.sh
        # sed -ri 's@(^\s+use_local_docker_tarball$)@#\1@g' ./arene-common_docker.sh
        sync
        ## Upgrade test docker.
        local cfg_docker_registry=$(grep DOCKER_REGISTRY ./sdk-hal-docker/.env | cut -d = -f 2)
        local cfg_docker_image_runtime_name=$(grep DOCKER_IMAGE_RUNTIME_NAME ./sdk-hal-docker/.env | cut -d = -f 2)
        local cfg_docker_image_runtime_tag=$(grep DOCKER_IMAGE_RUNTIME_TAG ./sdk-hal-docker/.env | cut -d = -f 2)
        local cfg_docker_image_hal_name=$(grep DOCKER_IMAGE_HAL_NAME ./sdk-hal-docker/.env | cut -d = -f 2)
        local cfg_docker_image_hal_tag=$(grep DOCKER_IMAGE_HAL_TAG ./sdk-hal-docker/.env | cut -d = -f 2)
        local curr_docker_image_runtime_tag=$(docker images  */${cfg_docker_image_runtime_name} --format "{{.Tag}}")
        local curr_docker_image_hal_tag=$(docker images  */${cfg_docker_image_hal_name} --format "{{.Tag}}")

        ### Stop and delete old test runtime and hal docker container
        local curr_container_runtime_id=$(docker ps -f ancestor=${cfg_docker_registry}/${cfg_docker_image_runtime_name}:${curr_docker_image_runtime_tag} --format "{{.ID}}")
        local curr_container_hal_id=$(docker ps -f ancestor=${cfg_docker_registry}/${cfg_docker_image_hal_name}:${curr_docker_image_hal_tag} --format "{{.ID}}")
        #### Stop and delete old test runtime docker container
        if [[ "" != ${curr_container_runtime_id} ]]; then
            echo "[INFO] Stop and delete old test runtime docker container."  >> ${log}
            # stop old test docker container
            docker stop ${curr_container_runtime_id}
            if [[ $?  -ne 0 ]]; then
                echo "[ERR ] line:${LINENO} Failed to stop runtime docker container.ID=>${curr_container_runtime_id}" | tee -a ${log}
                echo "======================================================"      >> ${log}
                return 1
            fi

            # delete old test docker container
            docker rm -f ${curr_container_runtime_id}
            if [[ $?  -ne 0 ]]; then
                echo "[ERR ] line:${LINENO} Failed to delete docker container.ID=>${curr_container_runtime_id}"  | tee -a ${log}
                echo "======================================================"      >> ${log}
                return 1
            fi
        fi

        #### Stop and delete old test hal docker container
        if [[ "" != ${curr_container_hal_id} ]]; then
            echo "[INFO] Stop and delete old test hal docker container."  >> ${log}
            # stop old test docker container
            docker stop ${curr_container_hal_id}
            if [[ $?  -ne 0 ]]; then
                echo "[ERR ] line:${LINENO} Failed to stop runtime docker container.ID=>${curr_container_hal_id}" | tee -a ${log}
                echo "======================================================"      >> ${log}
                return 1
            fi

            # delete old test docker container
            docker rm -f ${curr_container_hal_id}
            if [[ $?  -ne 0 ]]; then
                echo "[ERR ] line:${LINENO} Failed to delete docker container.ID=>${curr_container_hal_id}"  | tee -a ${log}
                echo "======================================================"      >> ${log}
                return 1
            fi
        fi

        ### Delete old test runtime and hal docker images
        local curr_image_runtime_id=$(docker images ${cfg_docker_registry}/${cfg_docker_image_runtime_name}:${curr_docker_image_runtime_tag} --format "{{.ID}}")
        local curr_image_hal_id=$(docker images ${cfg_docker_registry}/${cfg_docker_image_hal_name}:${curr_docker_image_hal_tag} --format "{{.ID}}")
        #### Delete old test runtime docker image
        if [[ ${curr_image_runtime_id} != "" ]]; then
            echo "[INFO] Delete old test runtime docker image."  >> ${log}
            docker rmi -f  ${curr_image_runtime_id}
            if [[ $?  -ne 0 ]]; then
                echo "[ERR ] line:${LINENO} Failed to delete old test runtime docker image.ID=>${curr_image_runtime_id}" | tee -a ${log}
                echo "======================================================"      >> ${log}
                return 1
            fi
        fi
        #### Delete old test hal docker image
        if [[ ${curr_image_hal_id} != "" ]]; then
            echo "[INFO] Delete old test hal docker image."  >> ${log}
            docker rmi -f  ${curr_image_hal_id}
            if [[ $?  -ne 0 ]]; then
                echo "[ERR ] line:${LINENO} Failed to delete old test hal docker image.ID=>${curr_image_hal_id}" | tee -a ${log}
                echo "======================================================"      >> ${log}
                return 1
            fi
        fi

        ### Delete old docker image file.
        echo "[INFO] Delete old docker image file." >> ${log}
        rm -fr ./sdk-hal-docker/*.tar.gz >> ${log} 2>&1
        if [[ $?  -ne 0 ]]; then
            echo "[ERR ] line:${LINENO} Failed to delete old docker image file." | tee -a ${log}
            echo "======================================================"      >> ${log}
            return 1
        fi

        ### Install the new test docker image and start container
        echo "[INFO] Install the new test docker image and start container." >> ${log}
        sleep 2

        export DISPLAY=:1.0
        (./${script_command} install)
        if [[ $?  -ne 0 ]]; then
            echo "[ERR ] line:${LINENO} Failed to install the new test docker image and start container." | tee -a ${log}
            echo "======================================================"      >> ${log}
            return 1
        fi
        sleep 2
        echo ""  >> ${log}

        ### check test docker installed result.
        local  curr_container_runtime_name=$(docker ps -f ancestor=${cfg_docker_registry}/${cfg_docker_image_runtime_name}:${cfg_docker_image_runtime_tag} --format "{{.Names}}")
        local  curr_container_hal_name=$(docker ps -f ancestor=${cfg_docker_registry}/${cfg_docker_image_hal_name}:${cfg_docker_image_hal_tag} --format "{{.Names}}")
        if [[ ${curr_container_runtime_name} == "" ]] || [[ ${curr_container_hal_name} == "" ]];then
            echo "[INFO] Restart the new test docker container." >> ${log}
            ./${script_command} restart >> ${log} 2>&1
            if [[ $?  -ne 0 ]]; then
                echo "[ERR ] line:${LINENO} Failed to restart the new test docker image container." | tee -a ${log}
                echo "======================================================"      >> ${log}
                return 1
            fi
            sleep 2
            echo ""  >> ${log}
        else
            echo "[INFO] Update the test container name in the configuration file."  >> ${log}
            sed -ri "s/(^RUNTIME_DOCKER_CONTAINER)=.*$/\1=${curr_container_runtime_name}/g"  ${cfg_file}
            if [[ $?  -ne 0 ]]; then
                echo "[ERR ] line:${LINENO} Failed to update the test container name. runtime name=>${curr_container_runtime_name}" | tee -a ${log}
                echo "======================================================"        >> ${log}
                return 1
            fi
            sed -ri "s/(^HAL_DOCKER_CONTAINER)=.*$/\1=${curr_container_hal_name}/g"  ${cfg_file}
            if [[ $?  -ne 0 ]]; then
                echo "[ERR ] line:${LINENO} Failed to update the test container name. hal name=>${curr_container_hal_name}" | tee -a ${log}
                echo "======================================================"        >> ${log}
                return 1
            fi
        fi

        ## Backup the new test docker image file to backup directory.
        echo "[INFO] Backup the new test docker image file to backup_path=>${backup_test_docker_image_path}"  >> ${log}
        if [[ ! -e ${backup_test_docker_image_path} ]]; then
            mkdir -p ${backup_test_docker_image_path}
        fi
        cp -fr ./sdk-hal-docker/*.tar.gz ${backup_test_docker_image_path} >> ${log} 2>&1
        if [[ $?  -ne 0 ]]; then
            echo "[ERR ] line:${LINENO} Failed to backup the new test docker image file to ${backup_test_docker_image_path}." | tee -a ${log}
            echo "======================================================"      >> ${log}
            return 1
        fi
        if [[ ${1} ]];then
            find ${docker_back_path} -type d -mtime +30 -exec rm -rf {} \;
            if [[ ! -e ${docker_back_path}/${1} ]]; then
                mkdir -p ${docker_back_path}/${1}
            fi
            cp -fr ./sdk-hal-docker/*.tar.gz  ${docker_back_path}/${1}   >> ${log} 2>&1
            if [[ $?  -ne 0 ]]; then
                echo "[ERR ] line:${LINENO} Failed to backup the new test docker to ${docker_back_path}/${1}." | tee -a ${log}
                echo "======================================================"      >> ${log}
                return 1
            fi
            echo "[INFO] Backup the new test docker image file to backup_path=>${docker_back_path}/${1}."  >> ${log}
        fi
    }
    popd  >> ${log}
    echo "[INFO] Successfully upgrade and backup test docker image."  >> ${log}

    # Save test docker info to file
    echo "[INFO] Save test docker info to file=>${test_docker_cfg}"  >> ${log}
    if [[ -e ${test_docker_cfg} ]]; then
        sed -ri "4,7s#(RUNTIME_DOCKER_IMAGE:).*#\1 ${cfg_docker_registry}/${cfg_docker_image_runtime_name}:${cfg_docker_image_runtime_tag}#g"  ${test_docker_cfg}
        sed -ri "4,7s#(RUNTIME_DOCKER_CONTAINER:).*#\1 ${curr_container_runtime_name}#g"                                      ${test_docker_cfg}
        sed -ri "4,7s#(HAL_DOCKER_IMAGE:).*#\1 ${cfg_docker_registry}/${cfg_docker_image_hal_name}:${cfg_docker_image_hal_tag}#g"              ${test_docker_cfg}
        sed -ri "4,7s#(HAL_DOCKER_CONTAINER:).*#\1 ${curr_container_hal_name}#g"                                                               ${test_docker_cfg}

        sed -ri "11,13s#(Repositories:).*#\1 ${git_repo}#g"            ${test_docker_cfg}
        sed -ri "11,13s#(Branch:).*#\1 ${git_branch}#g"                ${test_docker_cfg}
        sed -ri "11,13s#(CommitID:).*#\1 ${curr_version}#g"            ${test_docker_cfg}
    else
        echo "######################################################"  >  ${test_docker_cfg}
        echo "# Then current test docker info."                        >> ${test_docker_cfg}
        echo "######################################################"  >> ${test_docker_cfg}
        echo "RUNTIME_DOCKER_IMAGE: ${cfg_docker_registry}/${cfg_docker_image_runtime_name}:${cfg_docker_image_runtime_tag}"    >> ${test_docker_cfg}
        echo "RUNTIME_DOCKER_CONTAINER: ${curr_container_runtime_name}"                                                         >> ${test_docker_cfg}
        echo "HAL_DOCKER_IMAGE: ${cfg_docker_registry}/${cfg_docker_image_hal_name}:${cfg_docker_image_hal_tag}"                >> ${test_docker_cfg}
        echo "HAL_DOCKER_CONTAINER: ${curr_container_hal_name}"                                                                 >> ${test_docker_cfg}
        echo "######################################################"  >> ${test_docker_cfg}
        echo "# Then current test docker source code info."            >> ${test_docker_cfg}
        echo "######################################################"  >> ${test_docker_cfg}
        echo "Repositories: ${git_repo}"        >> ${test_docker_cfg}
        echo "Branch: ${git_branch}"            >> ${test_docker_cfg}
        echo "CommitID: ${curr_version}"        >> ${test_docker_cfg}
    fi

    # backup test docker images config info to backup directory
    echo "[INFO] Backup test docker images config info to backup_path=>${backup_test_docker_image_path}"  >> ${log}
    cp -fr  ${test_docker_cfg}  ${backup_test_docker_image_path}   >> ${log} 2>&1
    if [[ $?  -ne 0 ]]; then
        echo "[ERR ] line:${LINENO} Failed to backup test docker images config info to backup_path." | tee -a ${log}
        echo "======================================================"      >> ${log}
        return 1
    fi

    echo "[INFO] Successfully upgrade test docker image."              >> ${log}
    echo "======================================================"      >> ${log}
    echo ""                                                            >> ${log}
    return 0
}


######################################################
# Download fixed version docker.
# @param 
# none
# @ return 
#             0:Success
#             1:Failure
######################################################
function upgrade_fixed_ver_docker
{
    local runtime_url="https://artifactory-ha.tmc-stargate.com:443/artifactory/arene-os-services-cockpit-generic/docker/sdk-docker-runtime_${1}.tar.gz"
    local hal_mock_url="https://artifactory-ha.tmc-stargate.com:443/artifactory/arene-os-services-cockpit-generic/docker/sdk-docker-hal-mock_${1}.tar.gz"
    local runtime_docker="sdk-docker-runtime_${1}.tar.gz"
    local hal_mock_docker="sdk-docker-hal-mock_${1}.tar.gz"
    local docker_git_cfg=(${GIT_ENV_REPO[test_docker]//:/ })
    local git_repo=${docker_git_cfg[1]}
    local script_command=${env_path}/${git_repo}/${docker_git_cfg[3]}
    local docker_path=${env_path}/${git_repo}/sdk-hal-docker

    cd ${docker_path}
    rm -f ${runtime_docker} ${hal_mock_docker}

    # remove old docker images and containers.
    docker stop $(docker ps -a -q --filter name=sdk-hal-docker*)       >> ${log}
    if [[ $?  -ne 0 ]]; then
        echo "[ERR ] # Failed to docker stop !!!" >> ${log} 2>&1
        return 1
    fi
    docker rm $(docker ps -a -q --filter name=sdk-hal-docker*)         >> ${log}
    if [[ $?  -ne 0 ]]; then
        echo "[ERR ] # Failed to docker rm !!!" >> ${log} 2>&1
        return 1
    fi
    # docker rmi $(docker images -q arene-os*/*)                          >> ${log}

    

    local curr_image_hal_id=$(docker images arene-os-services-cockpit-docker.artifactory-ha.tmc-stargate.com/sdk-docker-hal-mock:${1} --format "{{.ID}}")
    if [[ ${curr_image_hal_id} != "" ]]; then
        docker stop  ${curr_image_hal_id} >> ${log} 2>&1
        docker rm  ${curr_image_hal_id} >> ${log} 2>&1
        if [[ $?  -ne 0 ]]; then
            echo "[ERR ] # Failed to docker image.ID=>${curr_image_hal_id}" >> ${log} 2>&1
            return 1
        fi
    fi
    local curr_image_runtime_id=$(docker images arene-os-services-cockpit-docker.artifactory-ha.tmc-stargate.com/sdk-docker-runtime:${1} --format "{{.ID}}")
    if [[ ${curr_image_runtime_id} != "" ]]; then
        docker stop  ${curr_image_runtime_id} >> ${log} 2>&1
        docker rm  ${curr_image_runtime_id} >> ${log} 2>&1
        if [[ $?  -ne 0 ]]; then
            echo "[ERR ] # Failed to docker image.ID=>${curr_image_runtime_id}" >> ${log} 2>&1
            return 1
        fi
    fi

    wget ${runtime_url}                                                 >> ${log} 2>&1
    if [[ $? -ne 0 ]]; then
        echo "[ERR ] line:${LINENO} Failed to wget ${runtime_url}. "  | tee -a ${log}
        echo "======================================================"      >> ${log}
        return 1
    fi 
    wget ${hal_mock_url}                                                   >> ${log} 2>&1
    if [[ $? -ne 0 ]]; then
        echo "[ERR ] line:${LINENO} Failed to wget ${hal_mock_url}. "  | tee -a ${log}
        echo "======================================================"      >> ${log}
        return 1
    fi

    # docker load
    # echo "Loading Docker Image(tarball)"                                      >> ${log}
    # docker load -i ${runtime_docker}
    # docker load -i ${hal_mock_docker}

    sed -ri "4s#(DOCKER_IMAGE_HAL_TAG=).*#\1${1}#g" ./.env
    sed -ri "6s#(DOCKER_IMAGE_RUNTIME_TAG=).*#\1${1}#g" ./.env

    cd ${env_path}/${git_repo}
    sed -ri 's/(^\s+setup$)/#\1/g' ./arene-ivi_docker.sh
    sed -ri 's/(^\s+xhost \+$)/#\1/g' ./arene-common_docker.sh
    sed -ri 's@(^\s+elif grep -q "artifactory-ha.tmc-stargate.com" ~/.netrc > /dev/null 2>&1; then$)@#\1@g' ./arene-common_docker.sh
    sed -ri 's@(^\s+fetch_docker_tarball$)@#\1@g' ./arene-common_docker.sh

    export DISPLAY=:0.0
    (${script_command} install 2>&1)  >> ${log}
    if [[ $? -ne 0 ]]; then
        echo "[ERR ] line:${LINENO} Failed to restart test environment. "  | tee -a ${log}
        echo "======================================================"      >> ${log}
        return 1
    fi 

    echo "[INFO] Successfully upgrade test docker image Ver = v${1}"  >> ${log}

    return 0
}

######################################################
# Upgrade fixed_ver_sdk.
# @param 
#             
# @ return 
#             0:Success
#             1:Failure
######################################################
function upgrade_fixed_ver_sdk
{
    echo "======================================================"      >> ${log}
    echo "[INFO] Start upgrade build sdk."                             >> ${log}
    local sdk_version=$(echo ${1} | awk -F '_' '{print $3}' |sed 's/.[A-Z]//g')
    local wget_sdk_url=$(echo ${WGET_SDK_URL} | sed "s/{--SDK_DATE_VERSION--}/${1}/g" | sed "s/{--SDK_VERSION--}/${sdk_version%-*}/g")
    ## The build sdk needs to be upgrade and backup.

        echo "[INFO] The build sdk needs to be upgrade and backup."                        >> ${log}
        pushd ${env_path}  >> ${log} 
        {
            ### Delet old build sdk.
            echo "[INFO] Delet old build sdk."                                  >> ${log}
            rm -fr sdk  >> ${log} 2>&1  && rm -fr arene-toolchain-cockpit-ivi-*-genericx86-64.sh  >> ${log} 2>&1
            if [[ $? -ne 0 ]]; then
                echo "[ERR ] line:${LINENO} Failed to delete old build sdk file. "  | tee -a ${log}
                echo "======================================================"      >> ${log}
                return 1
            fi 

            ### Download new build sdk.
            echo "[INFO] Download new build sdk."                               >> ${log}
            sdk_install_file=${wget_sdk_url##*/}
            wget -T 5 -t 3 -O ${sdk_install_file} ${wget_sdk_url} 2>./.wget_sdk_progress.log
            if [[ $?  -ne 0 ]]; then
                echo "[ERR ] line:${LINENO} Failed to download new build sdk. sdk url=${wget_sdk_url}." | tee -a ${log}
                echo "======================================================"      >> ${log}
                return 1
            fi


            ### Install new build sdk.
            echo "[INFO] Install new build sdk."                                >> ${log}
            # docker run --rm -it -v ~:/home/hosthome:ro -v ${WORK_PATH}:/workdir --name poky-$(id -un)-arene_source \
            docker run --rm -v ~:/home/hosthome:ro -v ${WORK_PATH}:/workdir --name poky-$(id -un)-arene_source \
                --workdir=/workdir ${BUILD_DOCKER_REPOSITORY}:${BUILD_DOCKER_TAG} \
                    bash -c " pwd; \
                        ls ./env; \
                        bash ./env/${sdk_install_file} -y -d ./env/sdk; \
                        exit" >> ${log} 2>&1
            if [[ $?  -ne 0 ]]; then
                echo "[ERR ] line:${LINENO} Failed to install new build sdk. sdk install file=>${sdk_install_file}" | tee -a ${log}
                echo "======================================================"      >> ${log}
                return 1
            else
                build_sdk_is_upgraded=true
            fi

            ### Backup the new build sdk installation file. 
            echo "[INFO] Backup the new build sdk installation file to backup_path=>${backup_build_sdk_path}/${1}"  >> ${log}
            if [[ ! -e ${backup_build_sdk_path}/${1} ]]; then
                mkdir -p ${backup_build_sdk_path}/${1}
            else
                rm -rf ${backup_build_sdk_path}/${1}/*
                :>${backup_build_sdk_path}/${1}/sdk.conf
            fi
            cp -fr ${sdk_install_file} ${backup_build_sdk_path}/${1}
            if [[ $?  -ne 0 ]]; then
                echo "[ERR ] line:${LINENO} Failed to backup the new build sdk installation file. sdk install file=>${sdk_install_file}" | tee -a ${log}
                echo "======================================================"      >> ${log}
                return 1
            fi
            
            # echo "SDK_VERSION=${sdk_version}"                      >> ${backup_build_sdk_path}/${1}/sdk.conf
            # echo "SDK_DATE_VERSION=${1}"                           >> ${backup_build_sdk_path}/${1}/sdk.conf
        }
        popd >> ${log}

        ### Update config file 
        echo "[INFO] Update the version of the build sdk in the configuration file."  >> ${log}
        sed -ri "s/(^SDK_DATE_VERSION_CURRENT)=.*$/\1=${1}/g"  ${cfg_file}
        if [[ $?  -ne 0 ]]; then
            echo "[ERR ] line:${LINENO} Failed to update build sdk version=>${1}" | tee -a ${log}
            echo "======================================================"      >> ${log}
            return 1
        fi

    # Save build sdk info
    echo "[INFO] Save build sdk info to file=>${build_sdk_cfg}"  >> ${log}
    echo "$wget_sdk_url"
    if [[ -e ${build_sdk_cfg} ]]; then
        sed -ri "4,6s#(BUILD_SDK_URL:).*#\1 ${wget_sdk_url}#g"            ${build_sdk_cfg}
        sed -ri "4,6s#(BUILD_SDK_VERSION:).*#\1 ${1}#g"    ${build_sdk_cfg}
        sed -ri "4,6s#(BUILD_SDK_FILE:).*#\1 ${sdk_install_file}#g"       ${build_sdk_cfg}
    else
        echo "######################################################"  >  ${build_sdk_cfg}
        echo "# The current build sdk info."                          >> ${build_sdk_cfg}
        echo "######################################################"  >> ${build_sdk_cfg}
        echo "BUILD_SDK_URL: ${wget_sdk_url}"                 >> ${build_sdk_cfg}
        echo "BUILD_SDK_VERSION: ${1}"         >> ${build_sdk_cfg}
        echo "BUILD_SDK_FILE: ${sdk_install_file}"            >> ${build_sdk_cfg}
    fi

    echo "[INFO] Successfully upgrade build sdk."                      >> ${log}
    echo "======================================================"      >> ${log}
    echo ""                                                            >> ${log}
    return 0
}

######################################################
# main
######################################################
if [[ $# -lt 1 ]] || [[ $# -gt 2 ]]; then
    echo "[ERR ] line:${LINENO} Incorrect number of parameters! count=$#" 1>&2
    usage
    exit 1
else
    case ${1} in
        "init-env")
            # start
            start_execute
            
            # manager backup file.
            echo "Manager backup file."
            time backup_manager
            if [[ $? -ne 0 ]]; then
                abnormal_exit
            fi 

            echo "Initialize or upgrade the test environment."
            # ${2} is release version,can be empty
            time upgrade_runtime_env ${2}
            if [[ $? -ne 0 ]]; then
                abnormal_exit
            fi 

            # Initialize or upgrade the build and test environment.
            echo "Initialize or upgrade the build environment."
            time upgrade_build_env
            if [[ $? -ne 0 ]]; then
                abnormal_exit
            fi

            normal_exit
            ;;
        "fixed-docker")
            # start
            start_execute
            # Download fixed version docker
            time upgrade_fixed_ver_docker $2
            if [[ $? -ne 0 ]]; then
                abnormal_exit
            fi 
            normal_exit
            ;;
        "fixed-sdk")
            # start
            start_execute
            # Download fixed version docker
            time upgrade_fixed_ver_sdk $2
            if [[ $? -ne 0 ]]; then
                abnormal_exit
            fi 
            normal_exit
            ;;
        *)
            echo "[ERR ] line:${LINENO} Parameter command is incorrect! command=${1}" 
            usage  
            exit 1
            ;;
    esac
fi
